package com.arvin.faceDetect.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.util.Log
import android.view.View
import com.google.mlkit.vision.face.Face

/**
 * 人脸检测结果的叠加显示视图
 * 负责在相机预览上绘制人脸检测框
 */
class FaceOverlayVie矩形框备份 @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    // 绘制人脸框的画笔
    private val paint = Paint().apply {
        color = Color.GREEN      // 框的颜色为绿色
        style = Paint.Style.STROKE  // 绘制空心矩形
        strokeWidth = 3f         // 减小线条宽度
        isAntiAlias = true      // 启用抗锯齿
    }

    // 当前检测到的人脸列表
    private var faces: List<Face> = emptyList()
    // 预览视图的尺寸
    private var previewWidth = 0
    private var previewHeight = 0
    // 原始图像的尺寸
    private var imageWidth = 0
    private var imageHeight = 0
    // 是否使用前置相机
    private var isFrontCamera = true
    // 图像旋转角度
    private var imageRotation = 0
    // 坐标转换矩阵
    private var transformationMatrix = Matrix()
    // 是否需要更新转换矩阵
    private var needUpdateTransformation = true

    /**
     * 更新人脸检测结果
     * @param newFaces 检测到的人脸列表
     * @param isFront 是否是前置相机
     * @param imgWidth 原始图像宽度
     * @param imgHeight 原始图像高度
     * @param rotation 图像旋转角度
     */
    fun updateFaces(
        newFaces: List<Face>,
        isFront: Boolean,
        imgWidth: Int,
        imgHeight: Int,
        rotation: Int
    ) {
        // 只在检测到人脸时打印日志
        if (newFaces.isNotEmpty()) {
            Log.d("FaceOverlayView", """
                收到人脸检测数据：
                人脸数量: ${newFaces.size}
                相机类型: ${if (isFront) "前置" else "后置"}
                图像尺寸: ${imgWidth}x${imgHeight}
                图像旋转: $rotation°
                ${newFaces.joinToString("\n") { face ->
                    """
                    人脸 ${face.trackingId ?: "未知ID"}:
                    边界框: ${face.boundingBox}
                    左眼: ${face.getLandmark(com.google.mlkit.vision.face.FaceLandmark.LEFT_EYE)?.position}
                    右眼: ${face.getLandmark(com.google.mlkit.vision.face.FaceLandmark.RIGHT_EYE)?.position}
                    旋转角度: 
                      - X轴: ${face.headEulerAngleX}
                      - Y轴: ${face.headEulerAngleY}
                      - Z轴: ${face.headEulerAngleZ}
                    """.trimIndent()
                }}
            """.trimIndent())
        }

        faces = newFaces
        isFrontCamera = isFront
        imageWidth = imgWidth
        imageHeight = imgHeight
        imageRotation = rotation
        needUpdateTransformation = true
        invalidate()
    }

    /**
     * 更新坐标转换矩阵
     * 将原始图像坐标系(720x720)转换为预览视图坐标系(1080x1100)
     */
    private fun updateTransformationIfNeeded() {
        if (!needUpdateTransformation) return

        // 重置变换矩阵，确保从初始状态开始转换
        transformationMatrix.reset()
        
        // 计算缩放比例
        // scaleX = 1080/720 = 1.5
        // scaleY = 1100/720 ≈ 1.53
        val scaleX = width.toFloat() / imageWidth.toFloat()
        val scaleY = height.toFloat() / imageHeight.toFloat()
        // 使用较小的缩放比例(1.5)以保持图像比例，避免拉伸
        val scale = minOf(scaleX, scaleY)
        
        Log.d("FaceOverlayView", """
            开始计算变换矩阵：
            预览视图尺寸: ${width}x${height}
            图像尺寸: ${imageWidth}x${imageHeight}
            比例: $scaleX vs $scaleY
        """.trimIndent())

        // 创建测试矩形(0,0,720,720)用于跟踪转换效果
        val testRect = RectF(0f, 0f, imageWidth.toFloat(), imageHeight.toFloat())
        Log.d("FaceOverlayView", "原始矩形: $testRect")

        // 计算居中偏移量
        // dx = (1080 - 720*1.5)/2 = 0
        // dy = (1100 - 720*1.5)/2 = 10
        val dx = (width - imageWidth * scale) / 2f
        val dy = (height - imageHeight * scale) / 2f
        Log.d("FaceOverlayView", """
            计算变换参数:
            缩放比例: scale=$scale (scaleX=$scaleX, scaleY=$scaleY)
            偏移量: dx=$dx, dy=$dy
        """.trimIndent())

        // 1. 先进行整体缩放(1.5倍)
        // 720x720 -> 1080x1080
        transformationMatrix.postScale(scale, scale)
        testRect.set(0f, 0f, imageWidth * scale, imageHeight * scale)
        Log.d("FaceOverlayView", "步骤1-缩放后: $testRect")

        // 2. 将图像移动到预览视图中心
        // 上下各留出10像素边距
        transformationMatrix.postTranslate(dx, dy)
        testRect.offset(dx, dy)
        Log.d("FaceOverlayView", "步骤2-平移后: $testRect")

        // 3. 前置相机需要水平镜像
        // 以预览视图中心(540,550)为轴进行镜像
        if (isFrontCamera) {
            transformationMatrix.postScale(-1f, 1f, width / 2f, height / 2f)
            val centerX = width / 2f
            testRect.set(
                centerX - (testRect.right - centerX),  // 镜像后的左边界
                testRect.top,                          // 保持垂直位置不变
                centerX + (centerX - testRect.left),   // 镜像后的右边界
                testRect.bottom                        // 保持垂直位置不变
            )
            Log.d("FaceOverlayView", "步骤3-镜像后: $testRect")
        }

        Log.d("FaceOverlayView", """
            最终变换结果:
            偏移量: dx=$dx, dy=$dy
            最终矩形: $testRect
        """.trimIndent())

        needUpdateTransformation = false
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        if (changed) {
            needUpdateTransformation = true  // 视图大小改变时需要更新变换矩阵
        }
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        
        if (faces.isEmpty()) return

        updateTransformationIfNeeded()

        for (face in faces) {
            drawFaceRect(canvas, face)
        }
    }

    /**
     * 绘制人脸检测框
     * 将ML Kit检测到的人脸坐标转换为预览视图上的坐标
     */
    private fun drawFaceRect(canvas: Canvas, face: Face) {
        // 1. 计算人脸框的中心点(355.5, 492.5)
        val centerX = (face.boundingBox.left + face.boundingBox.right) / 2f
        val centerY = (face.boundingBox.top + face.boundingBox.bottom) / 2f
        Log.d("FaceOverlayView", """
            绘制人脸框:
            原始边界: ${face.boundingBox}
            中心点: ($centerX, $centerY)
        """.trimIndent())

        // 2. 确保人脸框不超出图像边界(720x720)
        val adjustedRect = RectF(
            face.boundingBox.left.toFloat().coerceIn(0f, imageWidth.toFloat()),
            face.boundingBox.top.toFloat().coerceIn(0f, imageHeight.toFloat()),
            face.boundingBox.right.toFloat().coerceIn(0f, imageWidth.toFloat()),
            face.boundingBox.bottom.toFloat().coerceIn(0f, imageHeight.toFloat())
        )
        Log.d("FaceOverlayView", "调整后边界: $adjustedRect")

        // 3. 根据人脸Y轴旋转角度(-5.42°)调整框的大小
        val rotationY = Math.abs(face.headEulerAngleY)
        // 当旋转角度>30°时，宽度放大1.2倍，高度放大1.1倍
        // 当旋转角度>15°时，宽度放大1.1倍，高度不变
        // 其他情况宽度不变，高度缩小0.9倍
        val widthScale = if (rotationY > 30) 1.2f else if (rotationY > 15) 1.1f else 1.0f
        val heightScale = if (rotationY > 30) 1.1f else if (rotationY > 15) 1.0f else 0.9f
        
        // 4. 计算缩放后的矩形尺寸
        val newWidth = adjustedRect.width() * widthScale
        val newHeight = adjustedRect.height() * heightScale
        
        // 5. 以人脸中心点为基准创建新的矩形
        val scaledRect = RectF(
            centerX - newWidth / 2,    // 左边界
            centerY - newHeight / 2,   // 上边界
            centerX + newWidth / 2,    // 右边界
            centerY + newHeight / 2    // 下边界
        ).apply {
            // 确保缩放后的矩形仍在图像范围内
            left = left.coerceIn(0f, imageWidth.toFloat())
            top = top.coerceIn(0f, imageHeight.toFloat())
            right = right.coerceIn(0f, imageWidth.toFloat())
            bottom = bottom.coerceIn(0f, imageHeight.toFloat())
        }
        Log.d("FaceOverlayView", "缩放后边界: $scaledRect")

        // 6. 应用变换矩阵，将图像坐标转换为预览视图坐标
        val transformedRect = RectF(scaledRect)
        transformationMatrix.mapRect(transformedRect)
        Log.d("FaceOverlayView", "变换后边界: $transformedRect")

        // 7. 在画布上绘制人脸框
        canvas.drawRect(transformedRect, paint)

        // 8. 处理眼睛区域
        val leftEye = face.getLandmark(com.google.mlkit.vision.face.FaceLandmark.LEFT_EYE)?.position
        val rightEye = face.getLandmark(com.google.mlkit.vision.face.FaceLandmark.RIGHT_EYE)?.position
        if (leftEye != null && rightEye != null) {
            // 计算两眼之间的距离
            val eyeDistance = Math.hypot(
                (rightEye.x - leftEye.x).toDouble(),
                (rightEye.y - leftEye.y).toDouble()
            ).toFloat()
            
            // 根据人脸旋转角度调整眼睛区域大小
            val eyeScale = if (rotationY > 30) 0.4f else if (rotationY > 15) 0.3f else 0.2f
            // 创建包含两只眼睛的矩形区域
            val eyeRegion = RectF(
                Math.min(leftEye.x, rightEye.x) - eyeDistance * eyeScale,  // 左边界
                Math.min(leftEye.y, rightEye.y) - eyeDistance * eyeScale,  // 上边界
                Math.max(leftEye.x, rightEye.x) + eyeDistance * eyeScale,  // 右边界
                Math.max(leftEye.y, rightEye.y) + eyeDistance * eyeScale   // 下边界
            ).apply {
                // 确保眼睛区域在图像范围内
                left = left.coerceIn(0f, imageWidth.toFloat())
                top = top.coerceIn(0f, imageHeight.toFloat())
                right = right.coerceIn(0f, imageWidth.toFloat())
                bottom = bottom.coerceIn(0f, imageHeight.toFloat())
            }

            Log.d("FaceOverlayView", """
                眼睛区域:
                左眼: $leftEye
                右眼: $rightEye
                眼距: $eyeDistance
                边界: $eyeRegion
            """.trimIndent())

            // 9. 转换并绘制眼睛区域
            val transformedEyeRegion = RectF(eyeRegion)
            transformationMatrix.mapRect(transformedEyeRegion)
            canvas.drawRect(transformedEyeRegion, paint)
        }
    }

    /**
     * 设置预览视图尺寸
     * @param width 预览视图宽度
     * @param height 预览视图高度
     */
    fun setPreviewSize(width: Int, height: Int) {
        previewWidth = width
        previewHeight = height
        needUpdateTransformation = true  // 预览尺寸改变时需要更新变换矩阵
        invalidate()
    }
} 